<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="theme-color" content="#0078E7"><meta name="author" content="爱肖彤真是太好了"><meta name="copyright" content="爱肖彤真是太好了"><meta name="generator" content="Hexo 5.1.1"><meta name="theme" content="hexo-theme-yun"><title>RESTful API规范 | 工藤旧二の博客</title><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@900&amp;display=swap" media="none" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/star-markdown-css@0.1.19/dist/yun/yun-markdown.min.css"><script src="//at.alicdn.com/t/font_1140697_stqaphw3j4.js" async></script><script src="https://cdn.jsdelivr.net/npm/scrollreveal/dist/scrollreveal.min.js" defer></script><script>document.addEventListener("DOMContentLoaded", () => {
  [".post-card",".post-content img"].forEach((target)=> {
    ScrollReveal().reveal(target);
  })
});
</script><link rel="shortcut icon" type="image/svg+xml" href="/task/yun.ico"><link rel="mask-icon" href="/task/yun.ico" color="#0078E7"><link rel="alternate icon" href="/yun.ico"><link rel="preload" href="/task/css/hexo-theme-yun.css" as="style"><link rel="preload" href="/task/js/utils.js" as="script"><link rel="preload" href="/task/js/hexo-theme-yun.js" as="script"><link rel="prefetch" href="/task/js/sidebar.js" as="script"><link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin><link rel="stylesheet" href="/task/css/hexo-theme-yun.css"><link rel="alternate" href="/task/atom.xml" title="工藤旧二の博客" type="application/atom+xml"><script id="yun-config">
    const Yun = window.Yun || {};
    window.CONFIG = {"root":"/task/","title":"工藤旧二の博客","version":"0.9.7","anonymous_image":"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg","say":{"api":"https://v1.hitokoto.cn","hitokoto":true},"local_search":{"path":"/task/search.xml"},"fireworks":{"colors":["102, 167, 221","62, 131, 225","33, 78, 194"]}};
  </script><script>(function(){
  var bp = document.createElement('script');
  var curProtocol = window.location.protocol.split(':')[0];
  if (curProtocol === 'https') {
    bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
  }
  else {
    bp.src = 'http://push.zhanzhang.baidu.com/push.js';
  }
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(bp, s);
})();</script><meta name="description" content="这是一种web api接口的设计风格，比较适用于前后端分离的项目，它的特点就是一切数据都是资源。 与编程语言无关，任何一个框架都可以使用这种规范。 一、数据的安全保障url链接一般采用https进行传输，相比于http更加安全 二、接口特征表现用api关键字表示接口url：  https:&#x2F;&#x2F;api.baidu.com https:&#x2F;&#x2F;www.baidu.com&#x2F;api  三、多数据版本共存在ur">
<meta property="og:type" content="article">
<meta property="og:title" content="RESTful API规范">
<meta property="og:url" content="http://huang_zhao.gitee.io/task/2019/05/15/%E5%85%B6%E4%BB%96/RESTful%20API%E8%A7%84%E8%8C%83/index.html">
<meta property="og:site_name" content="工藤旧二の博客">
<meta property="og:description" content="这是一种web api接口的设计风格，比较适用于前后端分离的项目，它的特点就是一切数据都是资源。 与编程语言无关，任何一个框架都可以使用这种规范。 一、数据的安全保障url链接一般采用https进行传输，相比于http更加安全 二、接口特征表现用api关键字表示接口url：  https:&#x2F;&#x2F;api.baidu.com https:&#x2F;&#x2F;www.baidu.com&#x2F;api  三、多数据版本共存在ur">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2019-05-15T07:11:23.000Z">
<meta property="article:modified_time" content="2020-08-26T01:11:35.000Z">
<meta property="article:author" content="爱肖彤真是太好了">
<meta property="article:tag" content="resfulapi">
<meta name="twitter:card" content="summary"><script src="/task/js/ui/mode.js"></script><link rel="stylesheet" href="/task/css/prism.css" type="text/css"></head><body><script defer src="https://cdn.jsdelivr.net/npm/animejs@latest/anime.min.js"></script><script defer src="/task/js/ui/fireworks.js"></script><canvas class="fireworks"></canvas><div class="container"><a class="sidebar-toggle hty-icon-button" id="menu-btn"><div class="hamburger hamburger--spin" type="button"><span class="hamburger-box"><span class="hamburger-inner"></span></span></div></a><div class="sidebar-toggle sidebar-overlay"></div><aside class="sidebar"><script src="/task/js/sidebar.js"></script><ul class="sidebar-nav"><li class="sidebar-nav-item sidebar-nav-toc hty-icon-button sidebar-nav-active" data-target="post-toc-wrap" title="文章目录"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-list-ordered"></use></svg></li><li class="sidebar-nav-item sidebar-nav-overview hty-icon-button" data-target="site-overview-wrap" title="站点概览"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-passport-line"></use></svg></li></ul><div class="sidebar-panel" id="site-overview-wrap"><div class="site-info fix-top"><a class="site-author-avatar" href="/task/about/" title="爱肖彤真是太好了"><img width="96" loading="lazy" src="/task/Yun.png" alt="爱肖彤真是太好了"></a><div class="site-author-name"><a href="/task/about/">爱肖彤真是太好了</a></div><a class="site-name" href="/task/about/site.html">工藤旧二の博客</a><sub class="site-subtitle"></sub><div class="site-desciption"></div></div><nav class="site-state"><a class="site-state-item hty-icon-button icon-home" href="/task/" title="首页"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-home-4-line"></use></svg></span></a><div class="site-state-item"><a href="/task/archives/" title="归档"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-archive-line"></use></svg></span><span class="site-state-item-count">57</span></a></div><div class="site-state-item"><a href="/task/categories/" title="分类"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-folder-2-line"></use></svg></span><span class="site-state-item-count">2</span></a></div><div class="site-state-item"><a href="/task/tags/" title="标签"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="site-state-item-count">50</span></a></div><a class="site-state-item hty-icon-button" target="_blank" rel="noopener" href="https://yun.yunyoujun.cn" title="文档"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-settings-line"></use></svg></span></a></nav><hr style="margin-bottom:0.5rem"><div class="links-of-author"><a class="links-of-author-item hty-icon-button" rel="noopener" title="RSS" target="_blank" style="color:orange"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-rss-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="QQ" target="_blank" style="color:#12B7F5"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-qq-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="GitHub" target="_blank" style="color:#6e5494"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-github-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="微博" target="_blank" style="color:#E6162D"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-weibo-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="豆瓣" target="_blank" style="color:#007722"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-douban-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" href="https://music.163.com/#/user/home?id=552858287" title="网易云音乐" target="_blank" style="color:#C20C0C"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-netease-cloud-music-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="知乎" target="_blank" style="color:#0084FF"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-zhihu-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" href="https://space.bilibili.com/15081363" title="哔哩哔哩" target="_blank" style="color:#FF8EB3"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-bilibili-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Twitter" target="_blank" style="color:#1da1f2"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-twitter-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Telegram Channel" target="_blank" style="color:#0088CC"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-telegram-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="E-Mail" target="_blank" style="color:#8E71C1"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-mail-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Travelling" target="_blank" style="color:var(--hty-text-color)"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-send-plane-2-line"></use></svg></a></div><hr style="margin:0.5rem 1rem"><div class="links"><a class="links-item hty-icon-button" href="/task/links/" title="我的小伙伴们" style="color:dodgerblue"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-genderless-line"></use></svg></a></div><br><a class="links-item hty-icon-button" id="toggle-mode-btn" href="javascript:;" title="Mode" style="color: #f1cb64"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-contrast-2-line"></use></svg></a></div><div class="sidebar-panel sidebar-panel-active" id="post-toc-wrap"><div class="post-toc"><div class="post-toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E3%80%81%E6%95%B0%E6%8D%AE%E7%9A%84%E5%AE%89%E5%85%A8%E4%BF%9D%E9%9A%9C"><span class="toc-text">一、数据的安全保障</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C%E3%80%81%E6%8E%A5%E5%8F%A3%E7%89%B9%E5%BE%81%E8%A1%A8%E7%8E%B0"><span class="toc-text">二、接口特征表现</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89%E3%80%81%E5%A4%9A%E6%95%B0%E6%8D%AE%E7%89%88%E6%9C%AC%E5%85%B1%E5%AD%98"><span class="toc-text">三、多数据版本共存</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9B%9B%E3%80%81%E6%95%B0%E6%8D%AE%E5%8D%B3%E8%B5%84%E6%BA%90%EF%BC%8C%E5%9D%87%E4%BD%BF%E7%94%A8%E5%90%8D%E8%AF%8D%EF%BC%88%E5%8F%AF%E5%A4%8D%E6%95%B0%EF%BC%89"><span class="toc-text">四、数据即资源，均使用名词（可复数）</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%94%E3%80%81%E8%B5%84%E6%BA%90%E6%93%8D%E4%BD%9C%E7%94%B1%E8%AF%B7%E6%B1%82%E6%96%B9%E5%BC%8F%E5%86%B3%E5%AE%9A"><span class="toc-text">五、资源操作由请求方式决定</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%AD%E3%80%81%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87url%E5%90%8E%E7%9A%84%E5%8F%82%E6%95%B0%E8%BF%87%E6%BB%A4"><span class="toc-text">六、可以通过url后的参数过滤</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%83%E3%80%81%E5%93%8D%E5%BA%94%E7%8A%B6%E6%80%81%E7%A0%81"><span class="toc-text">七、响应状态码</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-%E6%AD%A3%E5%B8%B8%E5%93%8D%E5%BA%94"><span class="toc-text">1 正常响应</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-%E9%87%8D%E5%AE%9A%E5%90%91%E5%93%8D%E5%BA%94"><span class="toc-text">2 重定向响应</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%BC%82%E5%B8%B8"><span class="toc-text">3 客户端异常</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%BC%82%E5%B8%B8"><span class="toc-text">4 服务器异常</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%AB%E3%80%81-%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86%EF%BC%8C%E5%BA%94%E8%BF%94%E5%9B%9E%E9%94%99%E8%AF%AF%E4%BF%A1%E6%81%AF%EF%BC%8Cerror%E5%BD%93%E5%81%9Akey"><span class="toc-text">八、 错误处理，应返回错误信息，error当做key</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B9%9D%E3%80%81%E6%A0%B9%E6%8D%AE%E6%93%8D%E4%BD%9C%E7%9A%84%E4%B8%8D%E5%90%8C%EF%BC%8C%E8%BF%94%E5%9B%9E%E4%B8%8D%E5%90%8C%E7%9A%84%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F"><span class="toc-text">九、根据操作的不同，返回不同的数据格式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8D%81%E3%80%81%E5%8F%AF%E4%BB%A5%E5%9C%A8%E6%95%B0%E6%8D%AE%E4%B8%AD%E6%90%BA%E5%B8%A6%E9%9C%80%E8%A6%81%E8%AF%B7%E6%B1%82%E8%B5%84%E6%BA%90%E7%9A%84url%E5%9C%B0%E5%9D%80"><span class="toc-text">十、可以在数据中携带需要请求资源的url地址</span></a></li></ol></div></div></div></aside><main class="sidebar-translate" id="content"><div id="post"><article class="post-block" itemscope itemtype="https://schema.org/Article"><link itemprop="mainEntityOfPage" href="http://huang_zhao.gitee.io/task/task/2019/05/15/%E5%85%B6%E4%BB%96/RESTful%20API%E8%A7%84%E8%8C%83/"><span hidden itemprop="author" itemscope itemtype="https://schema.org/Person"><meta itemprop="name" content="爱肖彤真是太好了"><meta itemprop="description"></span><span hidden itemprop="publisher" itemscope itemtype="https://schema.org/Organization"><meta itemprop="name" content="工藤旧二の博客"></span><header class="post-header"><h1 class="post-title" itemprop="name headline">RESTful API规范</h1><div class="post-meta"><div class="post-time" style="display:block"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-calendar-line"></use></svg></span> <time title="创建时间：2019-05-15 15:11:23" itemprop="dateCreated datePublished" datetime="2019-05-15T15:11:23+08:00">2019-05-15</time><span class="post-meta-divider">-</span><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-calendar-2-line"></use></svg></span> <time title="修改时间：2020-08-26 09:11:35" itemprop="dateModified" datetime="2020-08-26T09:11:35+08:00">2020-08-26</time></div><span class="post-count"><span class="post-symbolcount"><span class="post-meta-item-icon" title="本文字数"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-file-word-line"></use></svg></span> <span title="本文字数">941</span><span class="post-meta-divider">-</span><span class="post-meta-item-icon" title="阅读时长"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-timer-line"></use></svg></span> <span title="阅读时长">3m</span></span></span><span class="post-busuanzi"><span class="post-meta-divider">-</span><span class="post-meta-item-icon" title="阅读次数"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-eye-line"></use></svg> <span id="busuanzi_value_page_pv"></span></span></span><div class="post-classify"><span class="post-category"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-folder-line"></use></svg></span> <span itemprop="about" itemscope itemtype="https://schema.org/Thing"><a class="category" href="/task/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/" style="--text-color:var(--hty-text-color)" itemprop="url" rel="index"><span itemprop="text">技术分享</span></a></span></span><span class="post-tag"><span class="post-meta-divider">-</span><a class="tag" href="/task/tags/resfulapi/" style="--text-color:var(--hty-text-color)"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="tag-name">resfulapi</span></a></span></div></div></header><section class="post-body" itemprop="articleBody"><div class="post-content markdown-body" style="--smc-primary:#0078E7;"><p>这是一种web api接口的设计风格，比较适用于前后端分离的项目，它的特点就是一切数据都是资源。</p>
<p>与编程语言无关，任何一个框架都可以使用这种规范。</p>
<h2 id="一、数据的安全保障"><a href="#一、数据的安全保障" class="headerlink" title="一、数据的安全保障"></a>一、数据的安全保障</h2><p>url链接一般采用https进行传输，相比于http更加安全</p>
<h2 id="二、接口特征表现"><a href="#二、接口特征表现" class="headerlink" title="二、接口特征表现"></a>二、接口特征表现</h2><p>用api关键字表示接口url：</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/">https://api.baidu.com</a></li>
<li><a target="_blank" rel="noopener" href="https://www.baidu.com/api">https://www.baidu.com/api</a></li>
</ul>
<h2 id="三、多数据版本共存"><a href="#三、多数据版本共存" class="headerlink" title="三、多数据版本共存"></a>三、多数据版本共存</h2><p>在url链接中标识数据版本</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/v1">https://api.baidu.com/v1</a></li>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/v2">https://api.baidu.com/v2</a></li>
</ul>
<p>v1，v2就相当于我们不同版本对应同样请求的接口</p>
<h2 id="四、数据即资源，均使用名词（可复数）"><a href="#四、数据即资源，均使用名词（可复数）" class="headerlink" title="四、数据即资源，均使用名词（可复数）"></a>四、数据即资源，均使用名词（可复数）</h2><ul>
<li><p>接口一般都是完成前后台数据的交互，交互的数据我们称之为资源</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/users">https://api.baidu.com/users</a></li>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/books">https://api.baidu.com/books</a></li>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/book">https://api.baidu.com/book</a></li>
</ul>
<p>注：一般提倡用资源的复数形式，在url链接中奖励不要出现操作资源的动词，错误示范：<a target="_blank" rel="noopener" href="https://api.baidu.com/delete-user">https://api.baidu.com/delete-user</a></p>
</li>
<li><p>特殊的接口可以出现动词，因为这些接口一般没有一个明确的资源，或是动词就是接口的核心含义</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/place/search">https://api.baidu.com/place/search</a></li>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/login">https://api.baidu.com/login</a></li>
</ul>
</li>
</ul>
<h2 id="五、资源操作由请求方式决定"><a href="#五、资源操作由请求方式决定" class="headerlink" title="五、资源操作由请求方式决定"></a>五、资源操作由请求方式决定</h2><p>操作资源一般都会涉及到增删改查，我们提供请求方式来标识增删改查动作</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/books">https://api.baidu.com/books</a> - get请求：获取所有书</li>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/books/1">https://api.baidu.com/books/1</a> - get请求：获取主键为1的书</li>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/books">https://api.baidu.com/books</a> - post请求：新增一本书书</li>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/books/1">https://api.baidu.com/books/1</a> - put请求：整体修改主键为1的书</li>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/books/1">https://api.baidu.com/books/1</a> - patch请求：局部修改主键为1的书</li>
<li><a target="_blank" rel="noopener" href="https://api.baidu.com/books/1">https://api.baidu.com/books/1</a> - delete请求：删除主键为1的书</li>
</ul>
<h2 id="六、可以通过url后的参数过滤"><a href="#六、可以通过url后的参数过滤" class="headerlink" title="六、可以通过url后的参数过滤"></a>六、可以通过url后的参数过滤</h2><ul>
<li><a target="_blank" rel="noopener" href="https://api.example.com/v1/zoos?limit=10%EF%BC%9A%E6%8C%87%E5%AE%9A%E8%BF%94%E5%9B%9E%E8%AE%B0%E5%BD%95%E7%9A%84%E6%95%B0%E9%87%8F">https://api.example.com/v1/zoos?limit=10：指定返回记录的数量</a></li>
<li><a target="_blank" rel="noopener" href="https://api.example.com/v1/zoos?offset=10%EF%BC%9A%E6%8C%87%E5%AE%9A%E8%BF%94%E5%9B%9E%E8%AE%B0%E5%BD%95%E7%9A%84%E5%BC%80%E5%A7%8B%E4%BD%8D%E7%BD%AE">https://api.example.com/v1/zoos?offset=10：指定返回记录的开始位置</a></li>
<li><a target="_blank" rel="noopener" href="https://api.example.com/v1/zoos?page=2&amp;per_page=100%EF%BC%9A%E6%8C%87%E5%AE%9A%E7%AC%AC%E5%87%A0%E9%A1%B5%EF%BC%8C%E4%BB%A5%E5%8F%8A%E6%AF%8F%E9%A1%B5%E7%9A%84%E8%AE%B0%E5%BD%95%E6%95%B0">https://api.example.com/v1/zoos?page=2&amp;per_page=100：指定第几页，以及每页的记录数</a></li>
<li><a target="_blank" rel="noopener" href="https://api.example.com/v1/zoos?sortby=name&amp;order=asc%EF%BC%9A%E6%8C%87%E5%AE%9A%E8%BF%94%E5%9B%9E%E7%BB%93%E6%9E%9C%E6%8C%89%E7%85%A7%E5%93%AA%E4%B8%AA%E5%B1%9E%E6%80%A7%E6%8E%92%E5%BA%8F%EF%BC%8C%E4%BB%A5%E5%8F%8A%E6%8E%92%E5%BA%8F%E9%A1%BA%E5%BA%8F">https://api.example.com/v1/zoos?sortby=name&amp;order=asc：指定返回结果按照哪个属性排序，以及排序顺序</a></li>
<li><a target="_blank" rel="noopener" href="https://api.example.com/v1/zoos?animal_type_id=1%EF%BC%9A%E6%8C%87%E5%AE%9A%E7%AD%9B%E9%80%89%E6%9D%A1%E4%BB%B6">https://api.example.com/v1/zoos?animal_type_id=1：指定筛选条件</a></li>
</ul>
<h2 id="七、响应状态码"><a href="#七、响应状态码" class="headerlink" title="七、响应状态码"></a>七、响应状态码</h2><h3 id="1-正常响应"><a href="#1-正常响应" class="headerlink" title="1 正常响应"></a>1 正常响应</h3><ul>
<li>响应状态码2xx<ul>
<li>200：常规请求</li>
<li>201：创建成功</li>
</ul>
</li>
</ul>
<h3 id="2-重定向响应"><a href="#2-重定向响应" class="headerlink" title="2 重定向响应"></a>2 重定向响应</h3><ul>
<li>响应状态码3xx<ul>
<li>301：永久重定向</li>
<li>302：暂时重定向</li>
</ul>
</li>
</ul>
<h3 id="3-客户端异常"><a href="#3-客户端异常" class="headerlink" title="3 客户端异常"></a>3 客户端异常</h3><ul>
<li>响应状态码4xx<ul>
<li>403：请求无权限</li>
<li>404：请求路径不存在</li>
<li>405：请求方法不存在</li>
</ul>
</li>
</ul>
<h3 id="4-服务器异常"><a href="#4-服务器异常" class="headerlink" title="4 服务器异常"></a>4 服务器异常</h3><ul>
<li>响应状态码5xx<ul>
<li>500：服务器异常</li>
</ul>
</li>
</ul>
<h2 id="八、-错误处理，应返回错误信息，error当做key"><a href="#八、-错误处理，应返回错误信息，error当做key" class="headerlink" title="八、 错误处理，应返回错误信息，error当做key"></a>八、 错误处理，应返回错误信息，error当做key</h2><pre class=" language-python"><code class="language-python"><span class="token punctuation">{</span>
    error<span class="token punctuation">:</span> <span class="token string">"无权限操作"</span>
<span class="token punctuation">}</span></code></pre>
<h2 id="九、根据操作的不同，返回不同的数据格式"><a href="#九、根据操作的不同，返回不同的数据格式" class="headerlink" title="九、根据操作的不同，返回不同的数据格式"></a>九、根据操作的不同，返回不同的数据格式</h2><pre class=" language-python"><code class="language-python">GET <span class="token operator">/</span>collection：返回资源对象的列表（数组）
GET <span class="token operator">/</span>collection<span class="token operator">/</span>resource：返回单个资源对象
POST <span class="token operator">/</span>collection：返回新生成的资源对象
PUT <span class="token operator">/</span>collection<span class="token operator">/</span>resource：返回完整的资源对象
PATCH <span class="token operator">/</span>collection<span class="token operator">/</span>resource：返回完整的资源对象
DELETE <span class="token operator">/</span>collection<span class="token operator">/</span>resource：返回一个空文档</code></pre>
<h2 id="十、可以在数据中携带需要请求资源的url地址"><a href="#十、可以在数据中携带需要请求资源的url地址" class="headerlink" title="十、可以在数据中携带需要请求资源的url地址"></a>十、可以在数据中携带需要请求资源的url地址</h2><pre class=" language-json"><code class="language-json"># Hypermedia API，RESTful API最好做到Hypermedia，即返回结果中提供链接，连向其他API方法，使得用户不查文档，也知道下一步应该做什么
<span class="token punctuation">{</span>
      <span class="token property">"status"</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
      <span class="token property">"msg"</span><span class="token operator">:</span> <span class="token string">"ok"</span><span class="token punctuation">,</span>
      <span class="token property">"results"</span><span class="token operator">:</span><span class="token punctuation">[</span>
        <span class="token punctuation">{</span>
            <span class="token property">"name"</span><span class="token operator">:</span><span class="token string">"肯德基(罗餐厅)"</span><span class="token punctuation">,</span>
            <span class="token property">"img"</span><span class="token operator">:</span> <span class="token string">"https://image.baidu.com/kfc/001.png"</span>
        <span class="token punctuation">}</span>
          ...
        <span class="token punctuation">]</span>
<span class="token punctuation">}</span></code></pre>
<p>比较好的接口返回</p>
<pre class=" language-json"><code class="language-json"># 响应数据要有状态码、状态信息以及数据本身
<span class="token punctuation">{</span>
      <span class="token property">"status"</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
      <span class="token property">"msg"</span><span class="token operator">:</span> <span class="token string">"ok"</span><span class="token punctuation">,</span>
      <span class="token property">"results"</span><span class="token operator">:</span><span class="token punctuation">[</span>
        <span class="token punctuation">{</span>
            <span class="token property">"name"</span><span class="token operator">:</span><span class="token string">"肯德基(罗餐厅)"</span><span class="token punctuation">,</span>
            <span class="token property">"location"</span><span class="token operator">:</span><span class="token punctuation">{</span>
                <span class="token property">"lat"</span><span class="token operator">:</span><span class="token number">31.415354</span><span class="token punctuation">,</span>
                <span class="token property">"lng"</span><span class="token operator">:</span><span class="token number">121.357339</span>
            <span class="token punctuation">}</span><span class="token punctuation">,</span>
            <span class="token property">"address"</span><span class="token operator">:</span><span class="token string">"月罗路2380号"</span><span class="token punctuation">,</span>
            <span class="token property">"province"</span><span class="token operator">:</span><span class="token string">"上海市"</span><span class="token punctuation">,</span>
            <span class="token property">"city"</span><span class="token operator">:</span><span class="token string">"上海市"</span><span class="token punctuation">,</span>
            <span class="token property">"area"</span><span class="token operator">:</span><span class="token string">"宝山区"</span><span class="token punctuation">,</span>
            <span class="token property">"street_id"</span><span class="token operator">:</span><span class="token string">"339ed41ae1d6dc320a5cb37c"</span><span class="token punctuation">,</span>
            <span class="token property">"telephone"</span><span class="token operator">:</span><span class="token string">"(021)56761006"</span><span class="token punctuation">,</span>
            <span class="token property">"detail"</span><span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">,</span>
            <span class="token property">"uid"</span><span class="token operator">:</span><span class="token string">"339ed41ae1d6dc320a5cb37c"</span>
        <span class="token punctuation">}</span>
          ...
        <span class="token punctuation">]</span>
<span class="token punctuation">}</span></code></pre>
</div><div id="reward-container"><span class="hty-icon-button button-glow" id="reward-button" title="打赏" onclick="var qr = document.getElementById(&quot;qr&quot;); qr.style.display = (qr.style.display === &quot;none&quot;) ? &quot;block&quot; : &quot;none&quot;;"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-hand-coin-line"></use></svg></span><div id="reward-comment">点我就给你看点有意思的</div><div id="qr" style="display:none;"><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/alipay.png"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/alipay.png" alt="支付宝" title="支付宝"></a><div><span style="color:#00A3EE"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-alipay-line"></use></svg></span></div></div><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/qqpay.jpg"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/qqpay.jpg" alt="QQ 支付" title="QQ 支付"></a><div><span style="color:#12B7F5"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-qq-line"></use></svg></span></div></div><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/wxpay.jpg"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/wxpay.jpg" alt="微信支付" title="微信支付"></a><div><span style="color:#2DC100"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-wechat-pay-line"></use></svg></span></div></div></div></div><ul class="post-copyright"><li class="post-copyright-author"><strong>本文作者：</strong>爱肖彤真是太好了</li><li class="post-copyright-link"><strong>本文链接：</strong><a href="http://huang_zhao.gitee.io/task/2019/05/15/%E5%85%B6%E4%BB%96/RESTful%20API%E8%A7%84%E8%8C%83/" title="RESTful API规范">http://huang_zhao.gitee.io/task/2019/05/15/%E5%85%B6%E4%BB%96/RESTful%20API%E8%A7%84%E8%8C%83/</a></li><li class="post-copyright-license"><strong>版权声明：</strong>本博客所有文章除特别声明外，均默认采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" target="_blank" rel="noopener" title="CC BY-NC-SA 4.0 "><svg class="icon"><use xlink:href="#icon-creative-commons-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-by-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-nc-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-sa-line"></use></svg></a> 许可协议。</li></ul></section></article><div class="post-nav"><div class="post-nav-item"><a class="post-nav-prev" href="/task/2019/07/25/python/%E6%A8%A1%E5%9D%97/python%E4%B8%80%E4%BA%9B%E5%AE%9E%E7%94%A8%E7%9A%84%E5%B0%8F%E5%B7%A5%E5%85%B7/" rel="prev" title="python一些实用的小工具"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-left-s-line"></use></svg><span class="post-nav-text">python一些实用的小工具</span></a></div><div class="post-nav-item"><a class="post-nav-next" href="/task/2019/03/15/python/%E6%A8%A1%E5%9D%97/python%E5%A5%87%E9%97%BB%E6%9D%82%E6%8A%80/" rel="next" title="python奇闻杂技"><span class="post-nav-text">python奇闻杂技</span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-right-s-line"></use></svg></a></div></div></div></main><footer class="sidebar-translate" id="footer"><div class="copyright"><span>&copy; 2019 – 2022 </span><span class="with-love" id="animate"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-cloud-line"></use></svg></span><span class="author"> 爱肖彤真是太好了</span></div><div class="powered"><span>由 <a href="https://hexo.io" target="_blank" rel="noopener">Hexo</a> 驱动 v5.1.1</span><span class="footer-separator">|</span><span>主题 - <a rel="noopener" href="https://github.com/YunYouJun/hexo-theme-yun" target="_blank"><span>Yun</span></a> v0.9.7</span></div><div class="live_time"><span>本博客已萌萌哒地运行</span><span id="display_live_time"></span><span class="moe-text">(●'◡'●)</span><script>function blog_live_time() {
  window.setTimeout(blog_live_time, 1000);
  const start = new Date('2019-04-12T00:00:00');
  const now = new Date();
  const timeDiff = (now.getTime() - start.getTime());
  const msPerMinute = 60 * 1000;
  const msPerHour = 60 * msPerMinute;
  const msPerDay = 24 * msPerHour;
  const passDay = Math.floor(timeDiff / msPerDay);
  const passHour = Math.floor((timeDiff % msPerDay) / 60 / 60 / 1000);
  const passMinute = Math.floor((timeDiff % msPerHour) / 60 / 1000);
  const passSecond = Math.floor((timeDiff % msPerMinute) / 1000);
  display_live_time.innerHTML = " " + passDay + " 天 " + passHour + " 小时 " + passMinute + " 分 " + passSecond + " 秒";
}
blog_live_time();
</script></div><div id="busuanzi"><script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><span id="busuanzi_container_site_uv" title="总访客量"><span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-user-line"></use></svg></span><span id="busuanzi_value_site_uv"></span></span><span class="footer-separator">|</span><span id="busuanzi_container_site_pv" title="总访问量"><span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-eye-line"></use></svg></span><span id="busuanzi_value_site_pv"></span></span></div></footer><a class="hty-icon-button" id="goUp" aria-label="back-to-top" href="#"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-up-s-line"></use></svg><svg class="progress-circle-container" viewBox="0 0 100 100"><circle class="progress-circle" id="progressCircle" cx="50" cy="50" r="48" fill="none" stroke="#0078E7" stroke-width="2" stroke-linecap="round"></circle></svg></a><a class="popup-trigger hty-icon-button icon-search" id="search" href="javascript:;" title="搜索"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-search-line"></use></svg></span></a><script>window.addEventListener("DOMContentLoaded", () => {
  // Handle and trigger popup window
  document.querySelector(".popup-trigger").addEventListener("click", () => {
    document.querySelector(".popup").classList.add("show");
    setTimeout(() => {
      document.querySelector(".search-input").focus();
    }, 100);
  });

  // Monitor main search box
  const onPopupClose = () => {
    document.querySelector(".popup").classList.remove("show");
  };

  document.querySelector(".popup-btn-close").addEventListener("click", () => {
    onPopupClose();
  });

  window.addEventListener("keyup", event => {
    if (event.key === "Escape") {
      onPopupClose();
    }
  });
});
</script><script src="/task/js/search/local-search.js" defer></script><div class="popup search-popup"><div class="search-header"><span class="popup-btn-close close-icon hty-icon-button"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-close-line"></use></svg></span></div><div class="search-input-container"><input class="search-input" id="local-search-input" type="text" placeholder="搜索..." value=""></div><div id="local-search-result"></div></div></div><script defer src="/task/js/utils.js"></script><script defer src="/task/js/hexo-theme-yun.js"></script></body></html>